home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i069: Jove, an emacs variant, version 4.9, Part13/21
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Jonathan Payne <jpayne@cs.rochester.edu>
- Posting-number: Volume 14, Issue 69
- Archive-name: jove4.9/part13
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 13 (of 21)."
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f './disp.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./disp.c'\"
- else
- echo shar: Extracting \"'./disp.c'\" \(28346 characters\)
- sed "s/^X//" >'./disp.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- X * is provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ***************************************************************************/
- X
- X#include "jove.h"
- X#include "ctype.h"
- X#include "termcap.h"
- X
- X
- X#ifdef MAC
- X# include "mac.h"
- X#else
- X# include <varargs.h>
- X# include <sys/stat.h>
- X#endif
- X
- X#include <signal.h>
- X
- X#ifdef MAC
- X# undef private
- X# define private
- X#endif
- X
- X#ifdef LINT_ARGS
- private void
- X#ifdef ID_CHAR
- X DeTab(int, char *, char *, int, int),
- X DelChar(int, int, int),
- X InsChar(int, int, int, char *),
- X#endif
- X DoIDline(int),
- X do_cl_eol(int),
- X ModeLine(Window *),
- X mode_app(char *),
- X GotoDot(void),
- X UpdLine(int),
- X UpdWindow(Window *, int);
- X
- private int
- X AddLines(int, int),
- X DelLines(int, int),
- X UntilEqual(int);
- X#else
- private void
- X#ifdef ID_CHAR
- X DeTab(),
- X DelChar(),
- X InsChar(),
- X#endif
- X DoIDline(),
- X do_cl_eol(),
- X GotoDot(),
- X ModeLine(),
- X mode_app(),
- X UpdLine(),
- X UpdWindow();
- private int
- X AddLines(),
- X DelLines(),
- X UntilEqual();
- X#endif /* LINT_ARGS */
- X
- X#ifdef MAC
- X# undef private
- X# define private static
- X#endif
- X
- int DisabledRedisplay = NO;
- X
- X/* Kludge windows gets called by the routines that delete lines from the
- X buffer. If the w->w_line or w->w_top are deleted and this procedure
- X is not called, the redisplay routine will barf. */
- X
- void
- ChkWindows(line1, line2)
- Line *line1;
- register Line *line2;
- X{
- X register Window *w = fwind;
- X register Line *lp;
- X
- X do {
- X for (lp = line1->l_next; lp != line2->l_next; lp = lp->l_next) {
- X if (lp == w->w_top)
- X w->w_flags |= W_TOPGONE;
- X if (lp == w->w_line)
- X w->w_flags |= W_CURGONE;
- X }
- X w = w->w_next;
- X } while (w != fwind);
- X}
- X
- extern int RingBell;
- X
- void
- redisplay()
- X{
- X extern int AbortCnt;
- X register Window *w = fwind;
- X int lineno,
- X done_ID = NO,
- X i;
- X register struct scrimage *des_p,
- X *phys_p;
- X
- X if (DisabledRedisplay == YES)
- X return;
- X curwind->w_line = curwind->w_bufp->b_dot;
- X curwind->w_char = curwind->w_bufp->b_char;
- X#ifdef MAC
- X InputPending = 0;
- X#else
- X if (InputPending = charp()) /* calls CheckEvent, which could */
- X return; /* result in a call to rediplay(). We don't want that. */
- X#endif
- X#ifdef JOB_CONTROL
- X if (UpdFreq)
- X sighold(SIGALRM);
- X#endif
- X if (RingBell) {
- X dobell(1);
- X RingBell = 0;
- X }
- X AbortCnt = BufSize; /* initialize this now */
- X if (UpdMesg)
- X DrawMesg(YES);
- X
- X for (lineno = 0, w = fwind; lineno < ILI; w = w->w_next) {
- X UpdWindow(w, lineno);
- X lineno += w->w_height;
- X }
- X
- X UpdModLine = 0; /* Now that we've called update window, we can
- X assume that the modeline will be updated. But
- X if while redrawing the modeline the user types
- X a character, ModeLine() is free to set this on
- X again so that the modeline will be fully drawn
- X at the next redisplay. */
- X
- X des_p = DesiredScreen;
- X phys_p = PhysScreen;
- X for (i = 0; i < ILI; i++, des_p++, phys_p++) {
- X if (!done_ID && (des_p->s_id != phys_p->s_id)) {
- X DoIDline(i);
- X done_ID = YES;
- X }
- X if ((des_p->s_flags & (DIRTY | L_MOD)) ||
- X (des_p->s_id != phys_p->s_id) ||
- X (des_p->s_vln != phys_p->s_vln) ||
- X (des_p->s_offset != phys_p->s_offset))
- X UpdLine(i);
- X if (InputPending)
- X goto ret;
- X }
- X
- X
- X if (Asking) {
- X Placur(LI - 1, min(CO - 2, calc_pos(mesgbuf, Asking)));
- X /* Nice kludge */
- X flusho();
- X } else
- X GotoDot();
- ret:
- X#ifdef JOB_CONTROL
- X if (UpdFreq)
- X sigrelse(SIGALRM);
- X#else
- X ; /* yuck */
- X#endif
- X#ifdef MAC
- X if(Windchange) docontrols();
- X#endif /* MAC */
- X}
- X
- X#ifndef IBMPC
- private void
- dobell(n)
- X{
- X while (--n >= 0) {
- X#ifndef MAC
- X if (VisBell && VB)
- X putstr(VB);
- X else
- X putpad(BL, 1);
- X#else
- X SysBeep(5);
- X#endif
- X }
- X flusho();
- X}
- X#endif /* IBMPC */
- X
- X/* find_pos() returns the position on the line, that C_CHAR represents
- X in LINE */
- X
- int
- find_pos(line, c_char)
- Line *line;
- X{
- X return calc_pos(lcontents(line), c_char);
- X}
- X
- int
- calc_pos(lp, c_char)
- register char *lp;
- register int c_char;
- X{
- X register int pos = 0;
- X register int c;
- X
- X
- X while ((--c_char >= 0) && ((c = *lp++) & CHARMASK) != 0) {
- X if (c == '\t')
- X pos += (tabstop - (pos % tabstop));
- X else if (isctrl(c))
- X pos += 2;
- X else
- X pos += 1;
- X }
- X return pos;
- X}
- X
- int UpdModLine = 0,
- X UpdMesg = 0,
- X CanScroll = 0;
- X
- private void
- DoIDline(start)
- X{
- X register struct scrimage *des_p = &DesiredScreen[start];
- X struct scrimage *phys_p = &PhysScreen[start];
- X register int i,
- X j;
- X
- X /* Some changes have been made. Try for insert or delete lines.
- X If either case has happened, Addlines and/or DelLines will do
- X necessary scrolling, also CONVERTING PhysScreen to account for the
- X physical changes. The comparison continues from where the
- X insertion/deletion takes place; this doesn't happen very often,
- X usually it happens with more than one window with the same
- X buffer. */
- X
- X if (!CanScroll)
- X return; /* We should never have been called! */
- X
- X for (i = start; i < ILI; i++, des_p++, phys_p++)
- X if (des_p->s_id != phys_p->s_id)
- X break;
- X
- X for (; i < ILI; i++) {
- X for (j = i + 1; j < ILI; j++) {
- X des_p = &DesiredScreen[j];
- X phys_p = &PhysScreen[j];
- X if (des_p->s_id != 0 && des_p->s_id == phys_p->s_id)
- X break;
- X if (des_p->s_id == PhysScreen[i].s_id) {
- X if (des_p->s_id == 0)
- X continue;
- X if (AddLines(i, j - i)) {
- X DoIDline(j);
- X return;
- X }
- X break;
- X }
- X if ((des_p = &DesiredScreen[i])->s_id == phys_p->s_id) {
- X if (des_p->s_id == 0)
- X continue;
- X if (DelLines(i, j - i)) {
- X DoIDline(i);
- X return;
- X }
- X break;
- X }
- X }
- X }
- X}
- X
- X/* Make DesiredScreen reflect what the screen should look like when we are done
- X with the redisplay. This deals with horizontal scrolling. Also makes
- X sure the current line of the Window is in the window. */
- X
- int ScrollAll = NO;
- X
- private void
- UpdWindow(w, start)
- register Window *w;
- X{
- X Line *lp;
- X int i,
- X upper, /* top of window */
- X lower, /* bottom of window */
- X strt_col, /* starting print column of current line */
- X ntries = 0; /* # of tries at updating window */
- X register struct scrimage *des_p,
- X *phys_p;
- X Buffer *bp = w->w_bufp;
- X
- retry:
- X if (w->w_flags & W_CURGONE) {
- X w->w_line = bp->b_dot;
- X w->w_char = bp->b_char;
- X }
- X if (w->w_flags & W_TOPGONE)
- X CentWind(w); /* reset topline of screen */
- X w->w_flags &= ~(W_CURGONE | W_TOPGONE);
- X
- X /* make sure that the current line is in the window */
- X upper = start;
- X lower = upper + w->w_height - 1; /* don't include modeline */
- X for (i = upper, lp = w->w_top; i < lower && lp != 0; lp = lp->l_next, i++)
- X if (lp == w->w_line)
- X break;
- X if (i == lower || lp == 0) {
- X ntries += 1;
- X if (ntries == 1) {
- X CalcWind(w);
- X goto retry;
- X } else if (ntries == 2) {
- X w->w_top = w->w_line = w->w_bufp->b_first;
- X printf("\rERROR in redisplay: I got hopelessly lost!");
- X dobell(2);
- X goto retry;
- X } else if (ntries == 3) {
- X printf("\n\rOops, still lost, quitting ...\r\n");
- X finish(1);
- X }
- X }
- X
- X /* first do some calculations for the current line */
- X {
- X int diff = (w->w_flags & W_NUMLINES) ? 8 : 0,
- X end_col;
- X
- X strt_col = (ScrollAll == YES) ? w->w_LRscroll :
- X PhysScreen[i].s_offset;
- X end_col = strt_col + (CO - 2) - diff;
- X /* Right now we are displaying from strt_col to
- X end_col of the buffer line. These are PRINT
- X columns, not actual characters. */
- X w->w_dotcol = find_pos(w->w_line, w->w_char);
- X /* if the new dotcol is out of range, reselect
- X a horizontal window */
- X if ((PhysScreen[i].s_offset == -1) ||
- X (w->w_dotcol < strt_col) ||
- X (w->w_dotcol >= end_col)) {
- X if (w->w_dotcol < ((CO - 2) - diff))
- X strt_col = 0;
- X else
- X strt_col = w->w_dotcol - (CO / 2);
- X if (ScrollAll == YES) {
- X if (w->w_LRscroll != strt_col)
- X UpdModLine = YES;
- X w->w_LRscroll = strt_col;
- X }
- X }
- X w->w_dotline = i;
- X w->w_dotcol += diff;
- X }
- X
- X des_p = &DesiredScreen[upper];
- X phys_p = &PhysScreen[upper];
- X for (i = upper, lp = w->w_top; lp != 0 && i < lower; i++, des_p++, phys_p++, lp = lp->l_next) {
- X des_p->s_window = w;
- X des_p->s_lp = lp;
- X des_p->s_id = lp->l_dline & ~DIRTY;
- X des_p->s_flags = isdirty(lp) ? L_MOD : 0;
- X if (w->w_flags & W_NUMLINES)
- X des_p->s_vln = w->w_topnum + (i - upper);
- X else
- X des_p->s_vln = 0;
- X
- X if (lp == w->w_line)
- X des_p->s_offset = strt_col;
- X else
- X des_p->s_offset = w->w_LRscroll;
- X }
- X
- X /* Is structure assignment faster than copy each field separately? */
- X if (i < lower) {
- X static struct scrimage dirty_plate = { 0, DIRTY, 0, 0, 0, 0 },
- X clean_plate = { 0, 0, 0, 0, 0, 0 };
- X
- X for (; i < lower; i++, des_p++, phys_p++)
- X if (phys_p->s_id != 0)
- X *des_p = dirty_plate;
- X else
- X *des_p = clean_plate;
- X }
- X
- X des_p->s_window = w;
- X des_p->s_flags = 0;
- X if (((des_p->s_id = (int) w->w_bufp) != phys_p->s_id) || UpdModLine)
- X des_p->s_flags = MODELINE | DIRTY;
- X#ifdef MAC
- X if(UpdModLine) Modechange = 1;
- X if(w == curwind && w->w_control) SetScrollBar(w->w_control);
- X#endif
- X}
- X
- X/* Write whatever is in mesgbuf (maybe we are Asking, or just printed
- X a message). Turns off the UpdateMesg line flag. */
- X
- void
- DrawMesg(abortable)
- X{
- X#ifndef MAC /* same reason as in redisplay() */
- X if (charp())
- X return;
- X#endif
- X i_set(ILI, 0);
- X if (swrite(mesgbuf, NO, abortable)) {
- X cl_eol();
- X UpdMesg = 0;
- X }
- X flusho();
- X}
- X
- X/* Goto the current position in the current window. Presumably redisplay()
- X has already been called, and curwind->{w_dotline,w_dotcol} have been set
- X correctly. */
- X
- private void
- GotoDot()
- X{
- X if (InputPending)
- X return;
- X Placur(curwind->w_dotline, curwind->w_dotcol -
- X PhysScreen[curwind->w_dotline].s_offset);
- X flusho();
- X}
- X
- private int
- UntilEqual(start)
- register int start;
- X{
- X register struct scrimage *des_p = &DesiredScreen[start],
- X *phys_p = &PhysScreen[start];
- X
- X while ((start < ILI) && (des_p->s_id != phys_p->s_id)) {
- X des_p += 1;
- X phys_p += 1;
- X start += 1;
- X }
- X
- X return start;
- X}
- X
- X/* Calls the routine to do the physical changes, and changes PhysScreen to
- X reflect those changes. */
- X
- private int
- AddLines(at, num)
- register int at,
- X num;
- X{
- X register int i;
- X int bottom = UntilEqual(at + num);
- X
- X if (num == 0 || num >= ((bottom - 1) - at))
- X return NO; /* we did nothing */
- X v_ins_line(num, at, bottom - 1);
- X
- X /* Now change PhysScreen to account for the physical change. */
- X
- X for (i = bottom - 1; i - num >= at; i--)
- X PhysScreen[i] = PhysScreen[i - num];
- X for (i = 0; i < num; i++)
- X PhysScreen[at + i].s_id = 0;
- X return YES; /* we did something */
- X}
- X
- private int
- DelLines(at, num)
- register int at,
- X num;
- X{
- X register int i;
- X int bottom = UntilEqual(at + num);
- X
- X if (num == 0 || num >= ((bottom - 1) - at))
- X return NO;
- X v_del_line(num, at, bottom - 1);
- X
- X for (i = at; num + i < bottom; i++)
- X PhysScreen[i] = PhysScreen[num + i];
- X for (i = bottom - num; i < bottom; i++)
- X PhysScreen[i].s_id = 0;
- X return YES;
- X}
- X
- X/* Update line linenum in window w. Only set PhysScreen to DesiredScreen
- X if the swrite or cl_eol works, that is nothing is interupted by
- X characters typed. */
- X
- private void
- UpdLine(linenum)
- register int linenum;
- X{
- X register struct scrimage *des_p = &DesiredScreen[linenum];
- X register Window *w = des_p->s_window;
- X
- X i_set(linenum, 0);
- X if (des_p->s_flags & MODELINE)
- X ModeLine(w);
- X else if (des_p->s_id) {
- X des_p->s_lp->l_dline &= ~DIRTY;
- X des_p->s_flags &= ~(DIRTY | L_MOD);
- X#ifdef ID_CHAR
- X if (!UseIC && (w->w_flags & W_NUMLINES))
- X#else
- X if (w->w_flags & W_NUMLINES)
- X#endif
- X (void) swrite(sprint("%6d ", des_p->s_vln), NO, YES);
- X
- X#ifdef ID_CHAR
- X if (UseIC) {
- X char outbuf[MAXCOLS],
- X *lptr;
- X int fromcol = (w->w_flags & W_NUMLINES) ? 8 : 0;
- X
- X if (w->w_flags & W_NUMLINES)
- X sprintf(outbuf, "%6d ", des_p->s_vln);
- X lptr = lcontents(des_p->s_lp);
- X DeTab(des_p->s_offset, lptr, outbuf + fromcol,
- X (sizeof outbuf) - 1 - fromcol,
- X des_p->s_window->w_flags & W_VISSPACE);
- X if (IDchar(outbuf, linenum, 0))
- X PhysScreen[linenum] = *des_p;
- X else if (i_set(linenum, 0), swrite(outbuf, NO, YES))
- X do_cl_eol(linenum);
- X else
- X PhysScreen[linenum].s_id = -1;
- X } else
- X#endif /* ID_CHAR */
- X if (BufSwrite(linenum))
- X do_cl_eol(linenum);
- X else
- X PhysScreen[linenum].s_id = -1;
- X } else if (PhysScreen[linenum].s_id) /* not the same ... make sure */
- X do_cl_eol(linenum);
- X}
- X
- private void
- do_cl_eol(linenum)
- register int linenum;
- X{
- X cl_eol();
- X PhysScreen[linenum] = DesiredScreen[linenum];
- X}
- X
- X#ifdef ID_CHAR
- X
- X/* From here to the end of the file is code that tries to utilize the
- X insert/delete character feature on some terminals. It is very confusing
- X and not so well written code, AND there is a lot of it. You may want
- X to use the space for something else. */
- X
- extern struct screenline *Screen;
- int IN_INSmode = 0;
- X
- int UseIC;
- X
- int DClen,
- X MDClen,
- X IClen,
- X MIClen,
- X IMlen,
- X CElen;
- X
- void
- disp_opt_init()
- X{
- X DClen = DC ? strlen(DC) : 0;
- X MDClen = M_DC ? strlen(M_DC) : 9999;
- X IClen = IC ? strlen(IC) : 0;
- X MIClen = M_IC ? strlen(M_IC) : 9999;
- X IMlen = IM ? strlen(IM) : 0;
- X CElen = CE ? strlen(CE) : 0;
- X
- X UseIC = (IC || IM || M_IC);
- X}
- X
- void
- INSmode(on)
- X{
- X if (on && !IN_INSmode) {
- X putpad(IM, 1);
- X IN_INSmode = YES;
- X } else if (!on && IN_INSmode) {
- X putpad(EI, 1);
- X IN_INSmode = NO;
- X }
- X}
- X
- private void
- DeTab(s_offset, buf, outbuf, limit, visspace)
- register char *buf;
- char *outbuf;
- X{
- X register char *phys_p = outbuf,
- X c;
- X register int pos = 0;
- X char *limitp = &outbuf[limit];
- X
- X#define OkayOut(ch) if ((pos++ >= s_offset) && (phys_p < limitp))\
- X *phys_p++ = ch;\
- X else
- X
- X while (c = *buf++) {
- X if (c == '\t') {
- X int nchars = (tabstop - (pos % tabstop));
- X
- X if (visspace) {
- X OkayOut('>');
- X nchars -= 1;
- X }
- X while (--nchars >= 0)
- X OkayOut(' ');
- X
- X } else if (isctrl(c)) {
- X OkayOut('^');
- X OkayOut(c == 0177 ? '?' : c + '@');
- X } else {
- X if (visspace && c == ' ')
- X c = '_';
- X OkayOut(c);
- X }
- X if (pos - s_offset >= CO) {
- X phys_p = &outbuf[CO - 1];
- X *phys_p++ = '!';
- X break;
- X }
- X }
- X *phys_p = 0;
- X}
- X
- X/* ID character routines full of special cases and other fun stuff like that.
- X It actually works though ...
- X
- X Returns Non-Zero if you are finished (no differences left). */
- X
- private int
- IDchar(new, lineno, col)
- register char *new;
- X{
- X register int i;
- X int j,
- X oldlen,
- X NumSaved;
- X register struct screenline *sline = &Screen[lineno];
- X
- X oldlen = sline->s_length - sline->s_line;
- X
- X for (i = col; i < oldlen && new[i] != 0; i++)
- X if (sline->s_line[i] != new[i])
- X break;
- X if (new[i] == 0 || i == oldlen)
- X return (new[i] == 0 && i == oldlen);
- X
- X for (j = i + 1; j < oldlen && new[j]; j++) {
- X if (new[j] == sline->s_line[i]) {
- X NumSaved = IDcomp(new + j, sline->s_line + i,
- X strlen(new)) + NumSimilar(new + i,
- X sline->s_line + i, j - i);
- X if (OkayInsert(NumSaved, j - i)) {
- X InsChar(lineno, i, j - i, new);
- X return(IDchar(new, lineno, j));
- X }
- X }
- X }
- X
- X for (j = i + 1; j < oldlen && new[i]; j++) {
- X if (new[i] == sline->s_line[j]) {
- X NumSaved = IDcomp(new + i, sline->s_line + j,
- X oldlen - j);
- X if (OkayDelete(NumSaved, j - i, new[oldlen] == 0)) {
- X DelChar(lineno, i, j - i);
- X return(IDchar(new, lineno, j));
- X }
- X }
- X }
- X return 0;
- X}
- X
- private int
- NumSimilar(s, t, n)
- register char *s,
- X *t;
- X{
- X register int num = 0;
- X
- X while (n--)
- X if (*s++ == *t++)
- X num += 1;
- X return num;
- X}
- X
- private int
- IDcomp(s, t, len)
- register char *s,
- X *t;
- X{
- X register int i;
- X int num = 0,
- X nonspace = 0;
- X char c;
- X
- X for (i = 0; i < len; i++) {
- X if ((c = *s++) != *t++)
- X break;
- X if (c != ' ')
- X nonspace++;
- X if (nonspace)
- X num += 1;
- X }
- X
- X return num;
- X}
- X
- private int
- OkayDelete(Saved, num, samelength)
- X{
- X /* If the old and the new are the same length, then we don't
- X * have to clear to end of line. We take that into consideration.
- X */
- X return ((Saved + (!samelength ? CElen : 0))
- X > min(MDClen, DClen * num));
- X}
- X
- private int
- OkayInsert(Saved, num)
- X{
- X register int n = 0;
- X
- X if (IC) /* Per character prefixes */
- X n = min(num * IClen, MIClen);
- X
- X if (IM && !IN_INSmode) {
- X /* Good terminal. Fewer characters in this case */
- X n += IMlen;
- X }
- X
- X n += num; /* The characters themselves */
- X
- X return Saved > n;
- X}
- X
- extern int CapCol;
- extern char *cursend;
- extern struct screenline *Curline;
- X
- private void
- DelChar(lineno, col, num)
- X{
- X register char *from,
- X *to;
- X register int i;
- X struct screenline *sp = (&Screen[lineno]);
- X
- X Placur(lineno, col);
- X if (M_DC && num > 1) {
- X char minibuf[16];
- X
- X sprintf(minibuf, M_DC, num);
- X putpad(minibuf, num);
- X } else {
- X for (i = num; --i >= 0; )
- X putpad(DC, 1);
- X }
- X
- X to = sp->s_line + col;
- X from = to + num;
- X
- X byte_copy(from, to, sp->s_length - from + 1);
- X clrline(sp->s_length - num, sp->s_length);
- X sp->s_length -= num;
- X}
- X
- private void
- InsChar(lineno, col, num, new)
- char *new;
- X{
- X register char *sp1,
- X *sp2, /* To push over the array. */
- X *sp3; /* Last character to push over. */
- X int i;
- X
- X i_set(lineno, 0);
- X sp2 = Curline->s_length + num;
- X
- X if (sp2 >= cursend) {
- X i_set(lineno, CO - num - 1);
- X cl_eol();
- X sp2 = cursend - 1;
- X }
- X Curline->s_length = sp2;
- X sp1 = sp2 - num;
- X sp3 = Curline->s_line + col;
- X
- X while (sp1 >= sp3)
- X *sp2-- = *sp1--;
- X
- X new += col;
- X byte_copy(new, sp3, num);
- X /* The internal screen is correct, and now we have to do
- X the physical stuff. */
- X
- X Placur(lineno, col);
- X if (IM) {
- X if (!IN_INSmode)
- X INSmode(1);
- X } else if (M_IC && num > 1) {
- X char minibuf[16];
- X
- X sprintf(minibuf, M_IC, num);
- X putpad(minibuf, num);
- X } else if (IC) {
- X for (i = 0; i < num; i++)
- X putpad(IC, 1);
- X }
- X for (i = 0; i < num; i++) {
- X putchar(new[i]);
- X if (IN_INSmode)
- X putpad(IP, 1);
- X }
- X CapCol += num;
- X}
- X
- X#endif /* ID_CHAR */
- X
- X#ifdef UNIX /* obviously ... no mail today if not Unix*/
- X
- X/* chkmail() returns nonzero if there is new mail since the
- X last time we checked. */
- X
- char Mailbox[FILESIZE]; /* initialized in main */
- int MailInt = 60; /* check no more often than 60 seconds */
- X#ifdef BIFF
- int BiffChk = NO; /* whether or not to turn off biff while in JOVE */
- X#endif
- X
- int
- chkmail(force)
- X{
- X time_t now;
- X static time_t last_chk = 0;
- X static int value = FALSE;
- X static off_t last_size = 0;
- X struct stat stbuf;
- X int last_val;
- X static time_t last_time = 0;
- X
- X time(&now);
- X if (!force && (now < last_chk + MailInt))
- X return value;
- X last_chk = now;
- X if (force)
- X last_time = now;
- X if (stat(Mailbox, &stbuf) < 0) {
- X value = FALSE;
- X return FALSE;
- X }
- X last_val = value;
- X value = ((stbuf.st_mtime > last_time) &&
- X (stbuf.st_size > 0) &&
- X (stbuf.st_size >= last_size) &&
- X (stbuf.st_mtime + 5 > stbuf.st_atime));
- X if (value == TRUE &&
- X ((value != last_val) || (stbuf.st_size != last_size)))
- X dobell(3);
- X if (stbuf.st_size < last_size)
- X last_time = now;
- X last_size = stbuf.st_size;
- X return value;
- X}
- X
- X#endif /* UNIX */
- X
- X/* Print the mode line. */
- X
- private char *mode_p,
- X *mend_p;
- int BriteMode = 1; /* modeline should standout */
- X
- private void
- mode_app(str)
- register char *str;
- X{
- X if (mode_p >= mend_p)
- X return;
- X while ((mode_p < mend_p) && (*mode_p++ = *str++))
- X ;
- X mode_p -= 1; /* back over the null */
- X}
- X
- char ModeFmt[120] = "%3c %w %[%sJOVE (%M) Buffer: %b \"%f\" %]%s%m*- %((%t)%s%)%e";
- X
- private void
- ModeLine(w)
- register Window *w;
- X{
- X extern int i_line;
- X extern char *pwd();
- X int n,
- X ign_some = NO;
- X char line[MAXCOLS],
- X *fmt = ModeFmt,
- X fillc,
- X c;
- X register Buffer *thisbuf = w->w_bufp;
- X register Buffer *bp;
- X
- X mode_p = line;
- X mend_p = &line[(sizeof line) - 1];
- X
- X#if defined(UNIX) || (defined (MSDOS) && !defined(IBMPC))
- X if (BriteMode != 0 && SO == 0)
- X BriteMode = 0;
- X fillc = BriteMode ? ' ' : '-';
- X#endif /* UNIX */
- X#ifdef IBMPC /* very subtle - don't mess up attributes too much */
- X fillc = '-'; /*BriteMode ? ' ' : '-';*/
- X#endif /* IBMPC */
- X#ifdef MAC
- X fillc = '_'; /* looks better on a Mac */
- X#endif /* MAC */
- X
- X while (c = *fmt++) {
- X if (c != '%') {
- X if (c == '\\')
- X if ((c = *fmt++) == '\0')
- X break;
- X if (!ign_some)
- X *mode_p++ = c;
- X continue;
- X }
- X if ((c = *fmt++) == '\0') /* char after the '%' */
- X break;
- X if (ign_some && c != ')')
- X continue;
- X n = 1;
- X if (c >= '0' && c <= '9') {
- X n = 0;
- X while (c >= '0' && c <= '9') {
- X n = n * 10 + (c - '0');
- X c = *fmt++;
- X }
- X }
- X switch (c) {
- X case '(':
- X if (w->w_next != fwind) /* Not bottom window. */
- X ign_some = YES;
- X break;
- X
- X case ')':
- X ign_some = NO;
- X break;
- X
- X case '[':
- X case ']':
- X {
- X char *strs = (c == '[') ? "[[[[[[[[[[" : "]]]]]]]]]]";
- X
- X mode_app(strs + 10 - RecDepth);
- X break;
- X }
- X
- X#ifdef UNIX
- X case 'C': /* check mail here */
- X if (chkmail(NO))
- X mode_app("[New mail]");
- X break;
- X
- X#endif /* UNIX */
- X
- X case 'M':
- X {
- X static char *mmodes[] = {
- X "Fundamental ",
- X "Text ",
- X "C ",
- X#ifdef LISP
- X "Lisp ",
- X#endif
- X 0
- X };
- X
- X mode_app(mmodes[thisbuf->b_major]);
- X
- X if (BufMinorMode(thisbuf, Fill))
- X mode_app("Fill ");
- X if (BufMinorMode(thisbuf, Abbrev))
- X mode_app("Abbrev ");
- X if (BufMinorMode(thisbuf, OverWrite))
- X mode_app("OvrWt ");
- X if (BufMinorMode(thisbuf, Indent))
- X mode_app("AI ");
- X if (InMacDefine)
- X mode_app("Def ");
- X mode_p -= 1; /* Back over the extra space. */
- X break;
- X }
- X
- X case 'c':
- X while (--n >= 0)
- X *mode_p++ = fillc;
- X break;
- X
- X#ifdef CHDIR
- X case 'd': /* print working directory */
- X mode_app(pr_name(pwd(), YES));
- X break;
- X#endif
- X
- X case 'e':
- X {
- X /* 2 space pad pluss padding for magic cookies */
- X char *last_p = &line[CO - 2 - (2 * SG)];
- X
- X while (mode_p < last_p)
- X *mode_p++ = fillc;
- X
- X goto outahere; /* %e means we're done! */
- X }
- X
- X case 'b':
- X mode_app(thisbuf->b_name);
- X break;
- X
- X case 'f':
- X case 'F':
- X if (thisbuf->b_fname == 0)
- X mode_app("[No file]");
- X else {
- X if (c == 'f')
- X mode_app(pr_name(thisbuf->b_fname, YES));
- X else
- X mode_app(basename(thisbuf->b_fname));
- X }
- X break;
- X
- X#ifdef LOAD_AV
- X case 'l':
- X {
- X double theavg;
- X char minibuf[10];
- X
- X get_la(&theavg);
- X theavg += .005; /* round to nearest .01 */
- X sprintf(minibuf, "%d.%02d",
- X (int) theavg,
- X (int)((theavg - (int) theavg) * 100));
- X mode_app(minibuf);
- X break;
- X }
- X#endif
- X
- X case 'm':
- X if (IsModified(w->w_bufp))
- X *mode_p++ = fmt[0];
- X else
- X *mode_p++ = fmt[1];
- X fmt += 2; /* skip two characters */
- X break;
- X
- X case 'n':
- X {
- X char tmp[16];
- X for (bp = world, n = 1; bp != 0; bp = bp->b_next, n++)
- X if (bp == thisbuf)
- X break;
- X
- X sprintf(tmp, "%d", n);
- X mode_app(tmp);
- X break;
- X }
- X
- X#ifdef IPROCS
- X case 'p':
- X if (thisbuf->b_type == B_PROCESS) {
- X char tmp[40];
- X
- X sprintf(tmp, "(%s)", (thisbuf->b_process == 0) ?
- X "No process" :
- X pstate(thisbuf->b_process));
- X mode_app(tmp);
- X break;
- X }
- X#endif
- X
- X case 's':
- X if (mode_p[-1] == ' ')
- X continue;
- X *mode_p++ = ' ';
- X break;
- X
- X case 't':
- X {
- X char timestr[12];
- X
- X mode_app(get_time((time_t *) 0, timestr, 11, 16));
- X break;
- X }
- X
- X case 'w':
- X if (w->w_LRscroll > 0)
- X mode_app(">");
- X }
- X }
- X
- outahere:
- X *mode_p = 0;
- X
- X /* Highlight mode line. */
- X if (BriteMode) {
- X#ifdef ID_CHAR
- X if (IN_INSmode)
- X INSmode(0);
- X#endif
- X#ifdef TERMCAP
- X putpad(SO, 1);
- X#else
- X SO_on();
- X#endif /* TERMCAP */
- X }
- X if (swrite(line, BriteMode, YES))
- X do_cl_eol(i_line);
- X else
- X UpdModLine = 1;
- X if (BriteMode)
- X#ifdef TERMCAP
- X putpad(SE, 1);
- X#else
- X SO_off();
- X#endif /* TERMCAP */
- X}
- X
- X/* This tries to place the current line of the current window in the
- X center of the window, OR to place it at the arg'th line of the window.
- X This also causes the horizontal position of the line to be centered,
- X if the line needs scrolling, or moved all the way back to the left,
- X if that's possible. */
- void
- RedrawDisplay()
- X{
- X int line;
- X Line *newtop = prev_line((curwind->w_line = curline), is_an_arg() ?
- X arg_value() : HALF(curwind));
- X
- X if ((line = in_window(curwind, curwind->w_line)) != -1)
- X PhysScreen[line].s_offset = -1;
- X if (newtop == curwind->w_top)
- X v_clear(FLine(curwind), FLine(curwind) + SIZE(curwind));
- X else
- X SetTop(curwind, newtop);
- X}
- X
- void
- v_clear(line1, line2)
- register int line1;
- X{
- X register struct scrimage *phys_p, *des_p;
- X
- X phys_p = &PhysScreen[line1];
- X des_p = &DesiredScreen[line1];
- X
- X while (line1 <= line2) {
- X i_set(line1, 0);
- X cl_eol();
- X phys_p->s_id = des_p->s_id = 0;
- X phys_p += 1;
- X des_p += 1;
- X line1 += 1;
- X }
- X}
- X
- void
- ClAndRedraw()
- X{
- X cl_scr(YES);
- X}
- X
- void
- NextPage()
- X{
- X Line *newline;
- X
- X if (Asking)
- X return;
- X if (arg_value() < 0) {
- X negate_arg_value();
- X PrevPage();
- X return;
- X }
- X if (arg_type() == YES)
- X UpScroll();
- X else {
- X if (in_window(curwind, curwind->w_bufp->b_last) != -1) {
- X rbell();
- X return;
- X }
- X newline = next_line(curwind->w_top, max(1, SIZE(curwind) - 1));
- X SetTop(curwind, curwind->w_line = newline);
- X if (curwind->w_bufp == curbuf)
- X SetLine(newline);
- X }
- X}
- X
- X#ifdef MSDOS /* kg */
- X
- void
- PageScrollUp()
- X{
- X int i, n;
- X
- X n = max(1, SIZE(curwind) - 1);
- X for (i=0; i<n; i++) {
- X UpScroll();
- X redisplay();
- X }
- X}
- X
- void
- PageScrollDown()
- X{
- X int i, n;
- X
- X n = max(1, SIZE(curwind) - 1);
- X for (i=0; i<n; i++) {
- X DownScroll();
- X redisplay();
- X }
- X}
- X#endif /* MSDOS */
- X
- void
- PrevPage()
- X{
- X Line *newline;
- X
- X if (Asking)
- X return;
- X if (arg_value() < 0) {
- X negate_arg_value();
- X NextPage();
- X return;
- X }
- X if (arg_type() == YES)
- X DownScroll();
- X else {
- X newline = prev_line(curwind->w_top, max(1, SIZE(curwind) - 1));
- X SetTop(curwind, curwind->w_line = newline);
- X if (curwind->w_bufp == curbuf)
- X SetLine(newline);
- X }
- X}
- X
- void
- UpScroll()
- X{
- X SetTop(curwind, next_line(curwind->w_top, arg_value()));
- X if ((curwind->w_bufp == curbuf) &&
- X (in_window(curwind, curline) == -1))
- X SetLine(curwind->w_top);
- X}
- X
- void
- DownScroll()
- X{
- X SetTop(curwind, prev_line(curwind->w_top, arg_value()));
- X if ((curwind->w_bufp == curbuf) &&
- X (in_window(curwind, curline) == -1))
- X SetLine(curwind->w_top);
- X}
- X
- int VisBell = NO,
- X RingBell = NO; /* So if we have a lot of errors ...
- X ring the bell only ONCE */
- void
- rbell()
- X{
- X RingBell = YES;
- X}
- X
- X/* Message prints the null terminated string onto the bottom line of the
- X terminal. */
- X
- void
- message(str)
- char *str;
- X{
- X if (InJoverc)
- X return;
- X UpdMesg = YES;
- X errormsg = NO;
- X if (str != mesgbuf)
- X null_ncpy(mesgbuf, str, (sizeof mesgbuf) - 1);
- X}
- X
- X/* End of Window */
- X
- void
- Eow()
- X{
- X if (Asking)
- X return;
- X SetLine(next_line(curwind->w_top, SIZE(curwind) - 1 -
- X min(SIZE(curwind) - 1, arg_value() - 1)));
- X if (!is_an_arg())
- X Eol();
- X}
- X
- X/* Beginning of Window */
- X
- void
- Bow()
- X{
- X if (Asking)
- X return;
- X SetLine(next_line(curwind->w_top, min(SIZE(curwind) - 1, arg_value() - 1)));
- X}
- X
- private int LineNo,
- X last_col,
- X DoAutoNL;
- private Window *old_wind; /* save the window we were in BEFORE
- X before we were called, if UseBuffers
- X is nonzero */
- X
- int UseBuffers = FALSE;
- int TOabort = 0;
- X
- X/* This initializes the typeout. If send-typeout-to-buffers is set
- X the buffer NAME is created (emptied if it already exists) and output
- X goes to the buffer. Otherwise output is drawn on the screen and
- X erased by TOstop() */
- X
- void
- TOstart(name, auto_newline)
- char *name;
- X{
- X if (UseBuffers) {
- X old_wind = curwind;
- X pop_wind(name, YES, B_SCRATCH);
- X } else
- X DisabledRedisplay = YES;
- X TOabort = LineNo = last_col = 0;
- X DoAutoNL = auto_newline;
- X}
- X
- X/* VARARGS1 */
- X
- void
- Typeout(fmt, va_alist)
- char *fmt;
- va_dcl
- X{
- X if (TOabort)
- X return;
- X
- X if (!UseBuffers && (LineNo == ILI - 1)) {
- X register int c;
- X
- X LineNo = 0;
- X last_col = 0;
- X f_mess("--more--");
- X if ((c = getchar()) != ' ') {
- X TOabort = YES;
- X if (c != AbortChar && c != RUBOUT)
- X Ungetc(c);
- X f_mess(NullStr);
- X return;
- X }
- X f_mess(NullStr);
- X }
- X
- X if (fmt) {
- X extern int i_col;
- X char string[132];
- X va_list ap;
- X
- X va_start(ap);
- X format(string, sizeof string, fmt, ap);
- X va_end(ap);
- X if (UseBuffers)
- X ins_str(string, NO);
- X else {
- X i_set(LineNo, last_col);
- X (void) swrite(string, NO, YES);
- X last_col = i_col;
- X }
- X }
- X if (!UseBuffers) {
- X PhysScreen[LineNo].s_id = -1;
- X if (fmt == 0 || DoAutoNL == YES) {
- X cl_eol();
- X flusho();
- X LineNo += 1;
- X last_col = 0;
- X }
- X } else if (fmt == 0 || DoAutoNL != 0)
- X ins_str("\n", NO);
- X}
- X
- void
- TOstop()
- X{
- X int c;
- X
- X if (UseBuffers) {
- X ToFirst();
- X SetWind(old_wind);
- X } else {
- X if (TOabort) {
- X DisabledRedisplay = NO;
- X return;
- X }
- X if (last_col != 0)
- X Typeout((char *) 0);
- X Typeout("----------");
- X cl_eol();
- X flusho();
- X c = getchar();
- X if (c != ' ')
- X Ungetc(c);
- X DisabledRedisplay = NO;
- X }
- X}
- END_OF_FILE
- if test 28346 -ne `wc -c <'./disp.c'`; then
- echo shar: \"'./disp.c'\" unpacked with wrong size!
- fi
- # end of './disp.c'
- fi
- echo shar: End of archive 13 \(of 21\).
- cp /dev/null ark13isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 21 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-